﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using MadLibrary;
using MadLibrary.Text;

namespace MadLibrary.Web
{
    /// <summary>
    /// Holds CSS styling property.
    /// </summary>
    public class CssProperty : IRefactorBuildable, IParsable
    {
        /// <summary>
        /// Gets or sets property name.
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Gets or sets property value.
        /// </summary>
        public string Value { get; set; }

        /// <summary>
        /// Creates new empty CSS property.
        /// </summary>
        public CssProperty()
        {
            this.Name = "";
            this.Value = "";
        }

        /// <summary>
        /// Creates CSS property with specified name.
        /// </summary>
        /// <param name="Name">Specifies name of new CSS property.</param>
        public CssProperty(string Name)
        {
            this.Name = Name;
            this.Value = "";
        }

        /// <summary>
        /// Creates CSS property with specified name and value.
        /// </summary>
        /// <param name="Name">Specifies name of new CSS property.</param>
        /// <param name="Value">Specifies value of new CSS property.</param>
        public CssProperty(string Name, string Value)
        {
            this.Name = Name;
            this.Value = Value;
        }

        /// <summary>
        /// Generates string from current CSS property.
        /// </summary>
        /// <param name="dept">Specifies actual tabulator dept of property.</param>
        /// <returns>String generated from current CSS property.</returns>
        string IRefactorBuildable.Build(int dept)
        {
            string ret = "";
            ret = string.Format("{0}{1}: {2};", "".Tabulate(dept + 1), this.Name, this.Value);
            return ret;
        }

        /// <summary>
        /// Tests if current CSS property equals specified object.
        /// </summary>
        /// <param name="obj">Specifies object which has to be compared with current CSS property.</param>
        /// <returns>Resutl of CSS property comparasion.</returns>
        public override bool Equals(object obj)
        {
            if(obj is CssProperty)
            {
                if((obj as CssProperty).Name == this.Name)
                    return true;
                else return false;
            }
            else return false;
        }

        /// <summary>
        /// Generates unique hash code of current CSS property.
        /// </summary>
        /// <returns>Unique hash code of current CSS property.</returns>
        public override int GetHashCode()
        {
            return (int)this.Name.ToCharArray()[0] + (int)this.Name.ToCharArray()[this.Name.ToCharArray().Length - 1] + this.Name.Length;
        }

        /// <summary>
        /// Compares two CSS properties.
        /// </summary>
        /// <param name="first">Specifies first CSS property passed for comparasion.</param>
        /// <param name="second">Specifies second CSS property passed for comparasion.</param>
        /// <returns>Result of comparasion.</returns>
        public static bool operator ==(CssProperty first, CssProperty second)
        {
            if(first.Name == second.Name)
                return true;
            else return false;
        }

        /// <summary>
        /// Compares two CSS properties.
        /// </summary>
        /// <param name="first">Specifies first CSS property passed for comparasion.</param>
        /// <param name="second">Specifies second CSS property passed for comparasion.</param>
        /// <returns>Result of comparasion.</returns>
        public static bool operator !=(CssProperty first, CssProperty second)
        {
            if(first.Name != second.Name)
                return true;
            else return false;
        }

        /// <summary>
        /// Parses specified string into current CssProperty object instance.
        /// </summary>
        /// <param name="input">Specifies string which has to be parsed.</param>
        void IParsable.Parse(string input)
        {
            Match m = Regex.Match(input, "([^=\\r\\n]*): ([^;]*);");
            if(m.Success)
            {
                this.Name = m.Groups[1].Value;
                this.Value = m.Groups[2].Value;
            }
        }
    }
}